<?php
/*
 * @Author: lokei
 * @Date: 2022-08-18 21:15:24
 * @LastEditors: lokei
 * @LastEditTime: 2022-09-26 16:56:10
 * @Description: 
 */

namespace App\Http\Controllers\Pay\Weixin;

use App\Http\Controllers\Controller;
use App\Models\Pay\ConfModel;
use App\Models\Pay\Record\PayRecordModel;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redis;
use WeChatPay\Crypto\Rsa;
use WeChatPay\Crypto\AesGcm;
use WeChatPay\Formatter;

class NotifyController extends Controller
{
    public function callback($pid, Request $request)
    {
        if ($pid != null && $pid != '') {
            $config = config()->all();
            $config['database']['connections']['mysql']['database'] = $pid . '_' . env('DB_DATABASE', 'forge');
            config($config);
        }

        $inWechatpaySignature = $request->header('Wechatpay-Signature'); // 请根据实际情况获取
        $inWechatpayTimestamp = $request->header('Wechatpay-Timestamp'); // 请根据实际情况获取
        $inWechatpaySerial = $request->header('Wechatpay-Serial'); // 请根据实际情况获取
        $inWechatpayNonce = $request->header('Wechatpay-Nonce'); // 请根据实际情况获取
        $inBody = file_get_contents('php://input'); // 请根据实际情况获取，例如: file_get_contents('php://input');

        $conf = ConfModel::first();
        $apiv3Key = $conf->signkey; // 在商户平台上设置的APIv3密钥

        // 根据通知的平台证书序列号，查询本地平台证书文件，
        // 假定为 `/path/to/wechatpay/inWechatpaySerial.pem`
        if ($pid != null && $pid != '') {
            $platformPublicKeyInstance = Rsa::from('file://' . env('ATTACHMENT_ROOT') . $pid . '/' . 'wxpay/' . 'wechatpay_' . $inWechatpaySerial . '.pem', Rsa::KEY_TYPE_PUBLIC);
        } else {
            $platformPublicKeyInstance = Rsa::from('file://' . env('ATTACHMENT_ROOT') . 'wxpay/' . 'wechatpay_' . $inWechatpaySerial . '.pem', Rsa::KEY_TYPE_PUBLIC);
        }
        
        // 检查通知时间偏移量，允许5分钟之内的偏移
        $timeOffsetStatus = 300 >= abs(Formatter::timestamp() - (int)$inWechatpayTimestamp);
        $verifiedStatus = Rsa::verify(
            // 构造验签名串
            Formatter::joinedByLineFeed($inWechatpayTimestamp, $inWechatpayNonce, $inBody),
            $inWechatpaySignature,
            $platformPublicKeyInstance
        );
        if ($timeOffsetStatus && $verifiedStatus) {
            // 转换通知的JSON文本消息为PHP Array数组
            $inBodyArray = (array)json_decode($inBody, true);
            // 使用PHP7的数据解构语法，从Array中解构并赋值变量
            ['resource' => [
                'ciphertext'      => $ciphertext,
                'nonce'           => $nonce,
                'associated_data' => $aad
            ]] = $inBodyArray;
            // 加密文本消息解密
            $inBodyResource = AesGcm::decrypt($ciphertext, $apiv3Key, $nonce, $aad);
            // 把解密后的文本转换为PHP Array数组
            $inBodyResourceArray = (array)json_decode($inBodyResource, true);
            $fields = array();
            $fields['sn'] = $inBodyResourceArray['out_trade_no'];
            if ($pid != null && $pid != '') {
                $fields['pid'] = $pid;
            }
            Redis::xAdd('pay_success', '*', $fields);

            $pay_record = PayRecordModel::where('tid', '=', $inBodyResourceArray['out_trade_no'])->first();
            $pay_record->status = '1';
            $pay_record->save();
        }

        echo 'success';
    }
}
